import React from 'react';
import loadjs from 'loadjs';

let insertSnippet;

export default class Editor extends React.Component {
  componentDidMount() {
    if (loadjs.isDefined('ace') && loadjs.isDefined('ace-tools')) {
      return this.renderEditor();
    }

    this.loadAce();
  }

  componentWillReceiveProps(nextProps) {
    const { selectId: newSelectId, value: newValue } = nextProps;
    const { selectId, value } = this.props;

    if (value === newValue) {
      window.editor && window.editor.focus();
    }

    if (newSelectId != selectId) {
      window.editor && window.editor.resize();
    }
  }

  loadAce = () => {
    const aceUrl = '/mobilemode/admin/dep/ace';

    loadjs(`${aceUrl}/ace.js`, 'ace');
    loadjs.ready('ace', () => {
      loadjs(`${aceUrl}/ext-language_tools.js`, 'ace-tools', {
        success: () => {
          this.renderEditor();
        }
      });
    });
  }

  renderEditor() {
    const that = this;
    let { mode = 'javascript', value = '', setEditor, onValueChange } = this.props;
    const ace = window.ace;
    const aceRequire = ace.acequire || ace.require;
    const { snippetManager } = aceRequire("ace/snippets");
    const { Editor } = aceRequire("./editor");
    const tools = aceRequire("ace/ext/language_tools");
    const scopes = require('./Scopes');

    if (!window.editor) {
      tools.addCompleter(scopes.EdcForm_completer());
      scopes.snippetScopces();
    }

    ace.config.set("basePath", "/mobilemode/admin/dep/ace");

    (function () {
      
      if (!insertSnippet) {
        insertSnippet = snippetManager.insertSnippet;
      }
 
      snippetManager.insertSnippet = function (editor, content) {
        var FOCUS_PLACEHOLDER = "::focus"; // 需要focus的占位符
        var mode = editor.session.getMode();

        if (!content.match(/\${.+}|\$[0-9]/g) && ~mode.$id.match(/(javascript|html)/g)) { // mode中默认${1}, ${2}...为占位符, 当为默认mode时, 则不转义$
        content = content.replace(/\$/g, "\\$"); // $作为函数关键字时 需要转移 如果$f,$u等函数
      }
      
      insertSnippet.call(snippetManager, editor, content);
      
      if (~content.indexOf(FOCUS_PLACEHOLDER)) { // 有占位符时, 删除占位符的同时, 将光标定位到该处
        editor.find(FOCUS_PLACEHOLDER);
        editor.remove(FOCUS_PLACEHOLDER);
      }
      editor.focus();
    };

      this.insertSnippet = function (content) {
        snippetManager.insertSnippet(this, content);
      };

    }).call(Editor.prototype);

    let dom = aceRequire("ace/lib/dom");

    dom.scrollbarWidth_orig = dom.scrollbarWidth_orig || dom.scrollbarWidth;
    dom.scrollbarWidth = function (doc) { return Math.max(20, dom.scrollbarWidth_orig(doc)) };

    const scriptCodeEle = that.scriptCodeRef;
    const editor = ace.edit(scriptCodeEle);

    that.refs.editor = editor;
    window.editor = editor;
    setEditor && setEditor(editor);
    importCssText(); // 修复编辑器字体受样式影响的问题
    editor.session.setMode("ace/mode/" + mode);
    editor.$blockScrolling = Infinity;
    editor.setShowPrintMargin(false); // 移除打印边距
    // enable autocompletion and snippets
    editor.setOptions({
      enableBasicAutocompletion: true,
      enableSnippets: true,
      enableLiveAutocompletion: true,
      includeScopes: ['EdcForm']
    });
    value && editor.setValue(value, true);
    editor.focus();
    editor.getSession().on('change', function (value, session) {
      onValueChange(session.getValue());
    });
  }

  render() {
    return (
      <div className='editor' ref={(el) => this.scriptCodeRef = el}></div>
    );
  }
}

function importCssText() {
  if (document.head.querySelector("#htmlEditorCss")) return;

  var style = document.createElement("style");

  style.type = "text/css";
  style.id = "htmlEditorCss";
  style.innerHTML = "\
      .ace_editor * {\
          font: 12px/normal 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro', monospace;\
      }";
  document.head.appendChild(style);
}
